#ifndef _OM_MUTEX_H_
#define _OM_MUTEX_H_

#include "OmPrerequisite.h"
#include "OmString.h"

namespace OmPublic
{
	// mutex
	class OmExport Mutex
	{
	public:
		Mutex(){}
		~Mutex(){}

		// create
		bool create();
		// destroy
		void destroy();
		// lock
		void lock();
		// unlock
		void unlock();

	protected:
		CRITICAL_SECTION mObject;			
	};

	// auto mutex, create when construct, destroy when destruct
	class OmExport AutoMutex : public Mutex
	{
	public:
		AutoMutex(){create();}
		~AutoMutex(){destroy();}
	};

	// auto mutex lock, lock the auto mutex when construct, unlock the auto mutex when destruct
	class OmExport AutoMutexLock 
	{
	public:
		AutoMutexLock(AutoMutex& mutex) : mMutex(mutex){mMutex.lock();}
		~AutoMutexLock(){mMutex.unlock();}

	private:
		AutoMutex& mMutex;
	};

	class ApplicationMutex
	{
	public:
		ApplicationMutex() : mHandle(0){}
		~ApplicationMutex(){if (mHandle) CloseHandle(mHandle);}

		void setName(const String & name){mName = name;}
		bool existed()
		{
			if (mName.empty()) // no name, do not check
				return false;

			mHandle = CreateMutex(NULL, FALSE, mName.c_str());
			if (!mHandle)
				return true;

			if (GetLastError() == ERROR_ALREADY_EXISTS)
			{
				CloseHandle(mHandle);
				mHandle = 0;
				return true;
			}
			return false;
		}

	private:
		String mName;
		HANDLE mHandle;
	};
}

#endif